/**
 * 前端统一请求工具函数
 */

// 响应数据类型定义
export interface ApiResponse<T = any> {
  success: boolean;
  data?: T;
  message?: string;
  code?: string;
  timestamp: string;
}

export interface PaginatedResponse<T = any> extends ApiResponse<T[]> {
  pagination?: {
    page: number;
    pageSize: number;
    total: number;
    totalPages: number;
  };
}

// 请求配置类型
export interface RequestConfig {
  baseURL?: string;
  timeout?: number;
  headers?: Record<string, string>;
  withCredentials?: boolean;
}

// 默认配置
const defaultConfig: RequestConfig = {
  baseURL: import.meta.env.VITE_API_URL || (import.meta.env.DEV ? 'http://localhost:3017' : 'http://47.92.153.176:3017'),
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
  withCredentials: false,
};

// 全局配置
let globalConfig = { ...defaultConfig };

/**
 * 设置全局配置
 */
export function setGlobalConfig(config: Partial<RequestConfig>) {
  globalConfig = { ...globalConfig, ...config };
}

/**
 * 获取完整的URL
 */
function getFullUrl(url: string, baseURL?: string): string {
  const base = baseURL || globalConfig.baseURL || '';
  if (url.startsWith('http://') || url.startsWith('https://')) {
    return url;
  }
  return `${base}${url.startsWith('/') ? '' : '/'}${url}`;
}

/**
 * 处理请求头
 */
function getHeaders(customHeaders?: Record<string, string>): Record<string, string> {
  const headers = { ...globalConfig.headers };
  
  // 添加认证token（如果存在）
  const token = localStorage.getItem('auth_token');
  if (token) {
    headers.Authorization = `Bearer ${token}`;
  }
  
  // 合并自定义头部
  if (customHeaders) {
    Object.assign(headers, customHeaders);
  }
  
  return headers;
}

/**
 * 处理响应
 */
async function handleResponse<T>(response: Response): Promise<ApiResponse<T>> {
  const contentType = response.headers.get('content-type');
  
  let data: any;
  if (contentType && contentType.includes('application/json')) {
    data = await response.json();
  } else {
    data = await response.text();
  }
  
  if (!response.ok) {
    // 处理HTTP错误
    const error: ApiResponse = {
      success: false,
      message: data.message || `HTTP Error: ${response.status}`,
      code: data.code || `HTTP_${response.status}`,
      timestamp: new Date().toISOString(),
    };
    throw error;
  }
  
  // 如果响应已经是标准格式，直接返回
  if (typeof data === 'object' && 'success' in data) {
    return data as ApiResponse<T>;
  }
  
  // 否则包装成标准格式
  return {
    success: true,
    data: data as T,
    message: 'Success',
    timestamp: new Date().toISOString(),
  };
}

/**
 * 基础请求函数
 */
async function request<T = any>(
  url: string,
  options: RequestInit & { config?: Partial<RequestConfig> } = {}
): Promise<ApiResponse<T>> {
  const { config, ...fetchOptions } = options;
  const requestConfig = { ...globalConfig, ...config };
  
  const fullUrl = getFullUrl(url, requestConfig.baseURL);
  const headers = getHeaders(fetchOptions.headers as Record<string, string>);
  
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), requestConfig.timeout);
  
  try {
    const response = await fetch(fullUrl, {
      ...fetchOptions,
      headers,
      signal: controller.signal,
      credentials: requestConfig.withCredentials ? 'include' : 'same-origin',
    });
    
    clearTimeout(timeoutId);
    return await handleResponse<T>(response);
  } catch (error) {
    clearTimeout(timeoutId);
    
    if (error instanceof Error) {
      if (error.name === 'AbortError') {
        throw {
          success: false,
          message: '请求超时',
          code: 'TIMEOUT',
          timestamp: new Date().toISOString(),
        } as ApiResponse;
      }
      
      throw {
        success: false,
        message: error.message,
        code: 'NETWORK_ERROR',
        timestamp: new Date().toISOString(),
      } as ApiResponse;
    }
    
    throw error;
  }
}

/**
 * GET 请求
 */
export function get<T = any>(
  url: string,
  params?: Record<string, any>,
  config?: Partial<RequestConfig>
): Promise<ApiResponse<T>> {
  let fullUrl = url;
  if (params) {
    const searchParams = new URLSearchParams();
    Object.entries(params).forEach(([key, value]) => {
      if (value !== undefined && value !== null) {
        searchParams.append(key, String(value));
      }
    });
    const queryString = searchParams.toString();
    if (queryString) {
      fullUrl += (url.includes('?') ? '&' : '?') + queryString;
    }
  }
  
  return request<T>(fullUrl, { method: 'GET', config });
}

/**
 * POST 请求
 */
export function post<T = any>(
  url: string,
  data?: any,
  config?: Partial<RequestConfig>
): Promise<ApiResponse<T>> {
  return request<T>(url, {
    method: 'POST',
    body: data ? JSON.stringify(data) : undefined,
    config,
  });
}

/**
 * PUT 请求
 */
export function put<T = any>(
  url: string,
  data?: any,
  config?: Partial<RequestConfig>
): Promise<ApiResponse<T>> {
  return request<T>(url, {
    method: 'PUT',
    body: data ? JSON.stringify(data) : undefined,
    config,
  });
}

/**
 * DELETE 请求
 */
export function del<T = any>(
  url: string,
  config?: Partial<RequestConfig>
): Promise<ApiResponse<T>> {
  return request<T>(url, { method: 'DELETE', config });
}

/**
 * 文件上传
 */
export function upload<T = any>(
  url: string,
  file: File | FormData,
  config?: Partial<RequestConfig>
): Promise<ApiResponse<T>> {
  const formData = file instanceof FormData ? file : new FormData();
  if (file instanceof File) {
    formData.append('file', file);
  }

  // 创建一个不包含 Content-Type 的 headers 对象
  const uploadHeaders: Record<string, string> = {};

  // 添加认证token（如果存在）
  const token = localStorage.getItem('auth_token');
  if (token) {
    uploadHeaders.Authorization = `Bearer ${token}`;
  }

  // 添加自定义头部（但排除 Content-Type）
  if (config?.headers) {
    Object.entries(config.headers).forEach(([key, value]) => {
      if (key.toLowerCase() !== 'content-type') {
        uploadHeaders[key] = value;
      }
    });
  }

  const fullUrl = getFullUrl(url, config?.baseURL);
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), config?.timeout || globalConfig.timeout);

  return fetch(fullUrl, {
    method: 'POST',
    body: formData,
    headers: uploadHeaders, // 不包含 Content-Type，让浏览器自动设置
    signal: controller.signal,
    credentials: config?.withCredentials || globalConfig.withCredentials ? 'include' : 'same-origin',
  }).then(async (response) => {
    clearTimeout(timeoutId);
    return await handleResponse<T>(response);
  }).catch((error) => {
    clearTimeout(timeoutId);

    if (error instanceof Error) {
      if (error.name === 'AbortError') {
        throw {
          success: false,
          message: '请求超时',
          code: 'TIMEOUT',
          timestamp: new Date().toISOString(),
        } as ApiResponse;
      }

      throw {
        success: false,
        message: error.message,
        code: 'NETWORK_ERROR',
        timestamp: new Date().toISOString(),
      } as ApiResponse;
    }

    throw error;
  });
}

// 导出默认的http客户端
export const http = {
  get,
  post,
  put,
  delete: del,
  upload,
  setGlobalConfig,
};
